Release 10.1A: OpenEdge Development:
ProDataSets


Defining a static Data-Source

Before you can populate a ProDataSet from a database, you must define a Data-Source object for each of its member temp-table buffers. A Data-Source names either a database buffer that supplies fields for a ProDataSet temp-table or a query name, which in turn references one or more buffers as well as defines a specific set of retrieval criteria. If you simply name the buffer, then Progress determines the query when a FILL occurs by examining the Data-Relation between the ProDataSet member buffer for the Data-Source and its parent. If it has no parent and there is no query definition, then all records from the database table are retrieved. If the Data-Source involves a join between two or more database tables, the user-written query is required to describe the relationship between the database tables.

The Data-Source is defined independently of any ProDataSet, using this statement:

 DEFINE DATA-SOURCE dsource-name FOR   
   [QUERY query-name ] [ source-buffer-phrase  [, source-buffer-phrase ] … ]. 

In this statement:

The syntax for the source-buffer-phrase is:

Syntax
 buffer-name [ KEYS ( { field [,field]… | ROWID } ) ]. 

In this phrase:

Note that the QUERY phrase and the source-buffer-phrase are not mutually exclusive. If you specify a query, then the query definition itself names the buffer or buffers it uses. However, you might still want to include a source-buffer-phrase in the Data-Source definition in order to define the fields that make up the unique key Progress should use to eliminate duplicate records when it is filling the table from the Data-Source, or to locate the database records for a temp-table record when you have updated the record.

If you specify a source-buffer-phrase without the QUERY phrase and the Data-Source is for a child of a Data-Relation, then Progress can generate the correct query when you fill the ProDataSet to load children of each of the parent records. Otherwise, the default is to load all records from the database table. If there is no QUERY phrase, then you can have only one source-buffer-phrase if you intend to use the Data-Source to fill a ProDataSet. Progress cannot automatically join multiple tables without a query definition.

Note that if you use the Data-Source solely to write changes back to the database using the Data-Source definition, then there is no need for a query at all.

Attaching Data-Sources

After you have defined a ProDataSet and its Data-Sources, you use the ATTACH-DATA-SOURCE method to associate them. This method, which is described in more detail later in this chapter, lets you specify which fields from the Data-Source go into the ProDataSet, and whether any are renamed in the process. You’ll learn how to use this method a little later. In the meantime, there are a few rules about how you specify the key fields for a Data-Source.

All the fields in the KEYS phrase must be represented in the ProDataSet buffer that the Data-Source is attached to. That is, they must not be excluded from the table in an EXCEPT list as part of the ATTACH-DATA-SOURCE method that associated the buffer and the Data-Source. The fields might be renamed in the ProDataSet buffer, however, and mapped in the ATTACH-DATA-SOURCE method. Instead of a field list, the KEYS phrase can specify (also within parentheses) the single keyword ROWID, in which case the table RowID is used as the key for retrieval and updating. In this case, there must be a field in the ProDataSet buffer that is mapped to the table ROWID at the time of the ATTACH.

If you don’t specify the KEYS phrase, then Progress uses one or more primary keys of the database tables to determine the key fields. Therefore, if the primary key is in fact the appropriate key to use to do a unique FIND on a record, then you do not need to specify it in the definition. If the KEYS phrase is not specified and the database tables do not have a unique primary key, then Progress has no way to locate a record for update or delete or to eliminate duplicate records. This means that if records in the ProDataSet are deleted or updated, the developer must provide an event procedure for that event that handles the operation—there can be no default support provided by Progress.

Because the KEYS list is associated with a specific buffer, you must include the source-buffer-phrase in the definition if you need to specify the KEYS. If you also specify a QUERY name, then the buffer list itself is really redundant, except to identify which keys go with which buffer, since the query definition also specified them. In this case Progress simply verifies that the list of buffers is the same.

Example

In the example for ProDataSet dsOrder, these are the Data-Source definitions, along with their queries:

DEFINE QUERY qOrder FOR Order, Customer, SalesRep. 
 DEFINE QUERY qItem  FOR ITEM. 
 DEFINE DATA-SOURCE srcOrder FOR QUERY qOrder  
    Order KEYS (OrderNum), Customer KEYS (CustNum), SalesRep KEYS (SalesRep). 
 DEFINE DATA-SOURCE srcOline FOR OrderLine. 
 DEFINE DATA-SOURCE srcItem FOR QUERY qItem ITEM  KEYS (ItemNum). 

You need a definition for query qOrder for two reasons. First, it is the top-level query, so unless you want all Orders and all their OrderLines and Items in the ProDataSet at the same time, which is unlikely (and which would be very expensive to load and pass between sessions), you will need to open that query with specific selection criteria for a single Order or a group of related orders. The second reason it’s needed is that it joins the Customer and SalesRep tables to the Order to pick up the Customer Name and SalesRep Name fields. You can’t do this join without the query because Progress won’t be able to join the tables for you automatically.

There is also a query qItem for the Item table so that under some circumstances you can specify that you want all Items loaded into the ProDataSet.

The Data-Source srcOrder shows you how to define the keys for each table in query qOrder. In this case, each of these is a unique primary key for the table, so the buffer list and the KEYS phrases are not strictly necessary. However, they provide you with explicit confirmation within your procedure of which keys are used to identify records.

Likewise, the phrase ITEM KEYS (ItemNum) is not strictly necessary in the Data-Source srcItem.

Data-Source as a separate object

Defining the Data-Source as a separate object allows you to define the ProDataSet without having to combine the Data-Source definitions with the ProDataSet definition. When a ProDataSet is passed to another session, the Data-Sources are not passed as part of the object, since they have no meaning on another session and their database tables cannot normally be referenced there. Separating the ProDataSet from its Data-Sources also allows a ProDataSet to attach and detach Data-Sources during program execution, and to switch Data-Sources when this is necessary, for example to retrieve data from different databases. You cannot pass a Data-Source as a parameter, but you can access the handle of an attached Data-Source through its ProDataSet if the ProDataSet is passed locally. You can also simply include the same Data-Source definition in multiple procedures where this is appropriate.

However, once the Data-Source is instantiated as an actual object instance, it can be attached to only one ProDataSet at a time.

Whether or not to define a query for a Data-Source

There are several ways in which you can use a Data-Source. How you are using it determines whether it is appropriate or necessary to associate it with an actual query or simply with one or more buffer names. In the following cases it is appropriate not to have a query for the Data-Source:

When you would not use a Data-Source at all

If you do not attach a Data-Source to a table before filling or updating the ProDataSet, then you must provide an event procedure to fill or update that table. Progress provides no default fill or update behavior in this case. If the source for the ProDataSet table is in fact one or more database tables, then you will normally want to define a Data-Source and attach it to the ProDataSet buffer to get the default behavior Progress provides. You can still extend that behavior in event procedures to further qualify which records go into the ProDataSet or to make other changes.

In some cases, however, your actual data source might not be a Progress or Data Server database at all. It could be a flat file that you read data from, an XML document that you process yourself, or some other source of data. In this case you simply do not define a Data-Source at all. Progress then depends on the event procedure code you write for the fill events for the table, and your own code must do the work of populating that table. If there’s no Data-Source for a temp-table and no supporting event procedure to replace it, then no data is loaded into that table, and no error results.

This gives you the flexibility to attach very different sources of data to the same ProDataSet without the ProDataSet definition or its business logic changing at all. At one time, the data might come from a file you read yourself. At another time, it might be moved into a database table. Or in a later release, Progress might natively support the nonstandard data source you use, and you can define a Data-Source object to handle it. You can do all this without changing anything at all in the ProDataSet itself.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095